package com.huhu.controller;

import com.huhu.entity.ArticleInfo;
import com.huhu.entity.UserInfo;
import com.huhu.entity.vo.UserInfoVO;
import com.huhu.service.ArticleService;
import com.huhu.service.UserService;
import com.huhu.util.AjaxResult;
import com.huhu.util.Constant;
import com.huhu.util.PasswordUtil;
import com.huhu.util.SessionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @Resource
    private RedisTemplate redisTemplate;

    @Autowired
    private ArticleService articleService;

    @Value("${imagepath}")
    private String imagePath;

    /**
     * 注册功能实现
     *
     * @param userInfoVO
     * @return
     */
    @RequestMapping("/reg")
    public Object reg(UserInfoVO userInfoVO) {
        // 1.非空校验
        if (userInfoVO == null || !StringUtils.hasLength(userInfoVO.getUsername())
                || !StringUtils.hasLength(userInfoVO.getPassword())
                || !StringUtils.hasLength(userInfoVO.getCheckCode())
                || !StringUtils.hasLength(userInfoVO.getCodeKey())) {
            return AjaxResult.fail(-1, "非法参数请求！");
        }
        // redis 里面 key 对应的真实的验证码
        String redisCodeValue = (String) redisTemplate.opsForValue().get(userInfoVO.getCodeKey());
        // 验证码错误
        if (!StringUtils.hasLength(redisCodeValue) || !redisCodeValue.equals(userInfoVO.getCheckCode())) {
            return AjaxResult.fail(-1, "验证码错误");
        }
        // 验证码正确，清除当前验证码
        redisTemplate.opsForValue().set(userInfoVO.getCodeKey(), "");
        // 密码进行加盐
        userInfoVO.setPassword(PasswordUtil.encrypt(userInfoVO.getPassword()));
        // 2.进行数据库添加操作
        int result = userService.addUser(userInfoVO);
        if (result == 1) {
            return AjaxResult.success("注册成功！", 1);
        } else {
            return AjaxResult.fail(-1, "数据库添加出错！");
        }
    }

    /**
     * 登录功能实现
     *
     * @param userInfoVO
     * @param request
     * @return
     */
    @RequestMapping("/login")
    public int login(UserInfoVO userInfoVO, HttpServletRequest request) {
        // 1.非空校验
        if (userInfoVO == null || !StringUtils.hasLength(userInfoVO.getUsername())
                || !StringUtils.hasLength(userInfoVO.getPassword())
                || !StringUtils.hasLength(userInfoVO.getCheckCode())
                || !StringUtils.hasLength(userInfoVO.getCodeKey())) {
            return 0;
        }
        // redis 里面 key 对应的真实的验证码
        String redisCodeValue = (String) redisTemplate.opsForValue().get(userInfoVO.getCodeKey());
        // 验证码错误
        if (!StringUtils.hasLength(redisCodeValue) || !redisCodeValue.equals(userInfoVO.getCheckCode())) {
            return -1;
        }
        // 验证码正确，清除当前验证码
        redisTemplate.opsForValue().set(userInfoVO.getCodeKey(), "");
        // 2.查询操作
        // 2.1.通过用户名查找对象
        UserInfo userInfo = userService.getUserByUsername(userInfoVO.getUsername());
        // 2.2 如果对象为空或者为无效对象，则返回-1
        if (userInfo == null || userInfo.getUid() <= 0) {
            return -1;
        }
        // 2.3 如果用户输入的密码与数据库输入密码不一致，则返回-1
//        if (!userInfoVO.getPassword().equals(userInfo.getPassword())) {
        if (!PasswordUtil.decrypt(userInfoVO.getPassword(), userInfo.getPassword())) {
            return -1;
        } else {
            HttpSession session = request.getSession();
            session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);
            userInfo.setPassword("");
            return 1;
        }
    }

    /**
     * 退出登录 【拦截】
     *
     * @param request
     * @return
     */
    @RequestMapping("/logout")
    public boolean logout(HttpServletRequest request) {
        // 设置false原因是：如果request里面没有session，那么不会去新建session
        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {
            // 清除 session
            session.removeAttribute(Constant.SESSION_USERINFO_KEY);
        }
        // 默认返回 true, 如果不清除 session, session 也有一个过期时间 30分钟
        return true;
    }

    /**
     * 获取个人信息(我的博客列表)
     *
     * @param request
     * @return
     */
    @RequestMapping("/myinfo")
    public UserInfo myinfo(HttpServletRequest request) {
        return SessionUtil.getLoginUser(request);
    }

    /**
     * 获取个人信息(博客详情页、个人信息页)
     *
     * @param request
     * @return
     */
    @RequestMapping("/info")
    public Object info(HttpServletRequest request) {
        // 从 session 工具类中拿用户登录信息
        UserInfo userInfo = SessionUtil.getLoginUser(request);
        if (userInfo == null || userInfo.getUid() <= 0) {
            return AjaxResult.fail(-2, "当前用户未登录！");
        }
        return AjaxResult.success(userInfo);
    }

    /**
     * 判断文章是否是当前登录人所写的
     *
     * @param aid
     * @param request
     * @return
     */
    @RequestMapping("/isartbyme")
    public Object isArticleByMe(Long aid, HttpServletRequest request) {
        if (aid == null || aid <= 0) {
            return AjaxResult.fail(-1, "参数有误! ");
        }
        UserInfo userInfo = SessionUtil.getLoginUser(request);
        if (userInfo == null || userInfo.getUid() <= 0) {
            return AjaxResult.fail(-2, "当前用户未登录! ");
        }
        ArticleInfo articleInfo = articleService.getDetailByAid(aid);
        if (articleInfo != null && articleInfo.getAid() >= 0
                && articleInfo.getUid() == userInfo.getUid()) {
            // 文章归属于当前登录人
            return AjaxResult.success(1);
        }
        return AjaxResult.success(0);
    }

    /**
     * 个人中心：保存头像
     *
     * @param file
     * @param request
     * @return
     */
    @RequestMapping("/save_photo")
    public Object savePhoto(MultipartFile file, HttpServletRequest request) {
        // 1.保存图片到服务器
        // 得到图片的后缀
        String imageType = file.getOriginalFilename().substring(
                file.getOriginalFilename().lastIndexOf("."));
        // 生成图片名称
        String imgName = UUID.randomUUID().toString()
                .replace("-", "") + imageType;
        try {
            file.transferTo(new File(imagePath + imgName));
        } catch (IOException e) {
            return AjaxResult.fail(-1, "图片上传失败！");
        }
        String imgUrl = "/image/" + imgName;
        // 2.将图片地址保存到数据库
        UserInfo userInfo = SessionUtil.getLoginUser(request);
        if (userInfo == null || userInfo.getUid() <= 0) {
            // 请先登录
            return AjaxResult.fail(-2, "请先登录！");
        }
        int result = userService.updatePhoto(userInfo.getUid(), imgUrl);
        if (result == 1) {
            // 更新头像到session中
            userInfo.setPhoto(imgUrl);
            HttpSession session = request.getSession();
            session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);
            return AjaxResult.success(imgUrl);
        } else {
            return AjaxResult.fail(-3, "数据库修改失败！");
        }
    }


    /**
     * 个人中心：修改用户名或密码
     *
     * @param username
     * @param oldPassword
     * @param newPassword
     * @param isUpdatePassword
     * @param request
     * @return
     */
    @RequestMapping("/update")
    public Object update(String username, String oldPassword, String newPassword, Boolean isUpdatePassword, HttpServletRequest request) {
        // 1.参数校验
        if (!StringUtils.hasLength(username)) {
            return AjaxResult.fail(-1, "非法参数！");
        }
        // 是否需要修改密码
        if (isUpdatePassword) {
            // 修改原密码
            if (!StringUtils.hasLength(oldPassword) || !StringUtils.hasLength(newPassword)) {
                return AjaxResult.fail(-1, "非法参数！");
            }
        }
        // 2.组装数据（从session获取用户）
        UserInfo userInfo = SessionUtil.getLoginUser(request);
        if (userInfo == null || userInfo.getUid() <= 0) {
            return AjaxResult.fail(-2, "请先登录！");
        }
        // 如果需要修改密码
        if (isUpdatePassword) {
            // 判断用户输入的旧密码和数据库的密码是否一致
            UserInfo dbUser=userService.getUserById(userInfo.getUid());
            boolean checkPassword = PasswordUtil.decrypt(oldPassword,dbUser.getPassword());
            if (!checkPassword) {
                return AjaxResult.fail(-3, "原密码输入错误！");
            }
            // 修改密码
            newPassword=PasswordUtil.encrypt(newPassword);
            userInfo.setPassword(newPassword);
        }
        // 3.修改数据库
        userInfo.setUsername(username);
        boolean result = userService.updateUser(userInfo);
        // 更新 session 中的用户名
        if(result) {
            userInfo.setUsername(username);
            HttpSession session = request.getSession();
            session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);
        }
        // 4.将结果返回给前端
        return AjaxResult.success(result ? 1 : 0);
    }
}
